package com.tajiang.business.bluetooth.utils;

import android.content.Context;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Base64;
import android.widget.Toast;

import com.gprinter.aidl.GpService;
import com.gprinter.command.EscCommand;
import com.gprinter.command.GpCom;
import com.gprinter.command.LabelCommand;
import com.gprinter.io.utils.GpUtils;
import com.tajiang.business.common.application.TJApp;
import com.tajiang.business.common.utils.CommandTools;
import com.tajiang.business.common.utils.LogUtils;
import com.tajiang.business.common.utils.NumberFormatUtils;
import com.tajiang.business.common.utils.RequestUtil;
import com.tajiang.business.common.utils.SharedPreferencesUtils;
import com.tajiang.business.common.utils.ToastUtils;
import com.tajiang.business.model.Order;
import com.tajiang.business.model.OrderGoods;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.Vector;

/**
 * Created by Administrator on 2016/7/26.
 * mPrinterId
 */
public class BTPrintUtils {

    public static final int PRINTER_ID = 0;//打印机ID
    private static final int LENGTH = 24;
    public static final int PRINT_MODE_SINGLE = 1;  //打印模式为单个打印
    public static final int PRINT_MODE_ALL = 2;     //打印模式为打印全部
    public static final int PRINT_MODE_AUTO = 3;     //打印模式来自动打印

    public static final String PRINT_SUCCESS = "0";  //蓝牙打印机成功接收打印 返回状态值为0
    public static final String PRINT_NO_PAPER = "2";  //打印设备没有纸 返回状态值为2
    public static final String PRINT_ERROR = "3";  //打印错误 返回状态值为3

    private static final String CHAR_TAB = "     ";

    private SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm", Locale.CHINA);
    private NumberFormat numberFormat = NumberFormat.getInstance();

    private int order_printed_count = 1;
    private static BTPrintUtils instance = null;

    public static int mConnectState = 0;//打印机连接状态 0-未连接 1-已连接

    private BTPrintUtils() {

    }

    public static BTPrintUtils getInstance() {

        if (instance == null) {

            synchronized (BTPrintUtils.class) {
                instance = new BTPrintUtils();
            }
        }
        return instance;
    }

    /**
     * （打印服务已在APP初始化的时候开启）
     * 调用蓝牙打印机进行打印
     */
    public void printTestPageClicked() {
        try {
            int num = 0;
            try {
                num = Integer.valueOf((String) SharedPreferencesUtils.get(SharedPreferencesUtils.PRINT_AMOUNT, "1"));
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < num; i++) {
                int rel = TJApp.getInstance().getmGpService().printeTestPage(0);
                LogUtils.i("ServiceConnection", "rel " + rel);
                GpCom.ERROR_CODE r = GpCom.ERROR_CODE.values()[rel];
                if (r != GpCom.ERROR_CODE.SUCCESS) {
                    ToastUtils.showShort(getErrorMsg(GpCom.getErrorText(r)));
                    return;
                }
            }
        } catch (RemoteException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

    @Nullable
    public String printSinglePage(Context context, Order order) {

        return AssembaleOrder(context, order);
    }

    private static GpService myprinter = null;

    /**
     * 组装票据,并且打印;
     *
     * @param context
     * @param order
     * @return
     */
    private String AssembaleOrder(Context context, Order order) {

//        try{
//
//            if (null == myprinter) {
//                myprinter = TJApp.getInstance().getmGpService();
//            }
//
//            if (myprinter == null) {
//                LogUtils.e("Exception: TJApp.GpService == null");
//                Toast.makeText(context, "请首先配置打印机", Toast.LENGTH_SHORT).show();
//                return null;
//            }
//
//            // 这里增加判断，是否连接正常 @20170506 by me
//            int li_PrinterConnectStatus = myprinter.getPrinterConnectStatus(PRINTER_ID);
//            Log.d("【525】", "打印机连接状态==>" + li_PrinterConnectStatus);
//            // 测试下来，=0的时候断开链接了，=5 的时候是保持成功的状态；
//
//            if (3 != li_PrinterConnectStatus && 5 != li_PrinterConnectStatus) {
//                LogUtils.e("【525】需要重新连接打印机..");
//                //!! OrderFragment.instance.myhandler.sendEmptyMessage(0);
//                Toast.makeText(context, "打印机已断开,请到【设置】-【打印设置】中重新连接", Toast.LENGTH_SHORT).show();
//                return null;
//            }
//        }catch (Exception ex){
//            LogUtils.e("【525】检查打印机状态时异常:"+ex.getMessage());
//        }

        if(RequestUtil.ERROR_USER_INFO.equals(RequestUtil.code)){
            ToastUtils.showShort("登录失效，请重新登录");
            return null;
        }

        Calendar calendar = Calendar.getInstance();
//        calendar.setTimeInMillis(order.getPaymentTime());
        EscCommand esc = new EscCommand();

        int rel = 0;//默认成功
        int num = 0;  //获取打印份数

        try {
            esc.addTurnUnderlineModeOnOrOff(EscCommand.UNDERLINE_MODE.OFF);

            // 设 置 打 印 居 中
            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
            esc.addSetCharcterSize(EscCommand.WIDTH_ZOOM.MUL_2, EscCommand.HEIGHT_ZOOM.MUL_2);

            /**
             * 订单编号，存储于本地，定时更新清楚今日订单
             */
            order_printed_count = (int) SharedPreferencesUtils.get(SharedPreferencesUtils.ORDER_PRINTED_COUNT, 1);
            String day_month_year = (String) SharedPreferencesUtils.get(SharedPreferencesUtils.DAY_MONTH_YEAR, "1999-11-11");
            if(!day_month_year.equals(CommandTools.getDate())){
                order_printed_count = 0;
            }

            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
            esc.addSetCharcterSize(EscCommand.WIDTH_ZOOM.MUL_2, EscCommand.HEIGHT_ZOOM.MUL_2);
            esc.addText("#" + NumberFormatUtils.IntegerFormat(order_printed_count + 1, 3) + "\n");

            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
            esc.addSetCharcterSize(EscCommand.WIDTH_ZOOM.MUL_2, EscCommand.HEIGHT_ZOOM.MUL_2);
            esc.addText("全民雷锋\n\n");

            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
            esc.addSetCharcterSize(EscCommand.WIDTH_ZOOM.MUL_1, EscCommand.HEIGHT_ZOOM.MUL_1);
            esc.addText(order.getShopName()  + "\n");

            esc.addSetCharcterSize(EscCommand.WIDTH_ZOOM.MUL_1, EscCommand.HEIGHT_ZOOM.MUL_1);
            esc.addText("*******************************\n\n");

            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
            esc.addText("送达时间：" + order.getDelyEndDate() + "\n");
            esc.addText("下单时间：" + order.getCreateDate() + "\n\n");
            esc.addText("备注：" + order.getBuyerRemark() + "\n");

            esc.addText("-------------------------------\n\n");

            if (order.getOrderItemList() != null) {

                for (OrderGoods goods : order.getOrderItemList()) {

                    esc.addSetCharcterSize(EscCommand.WIDTH_ZOOM.MUL_1, EscCommand.HEIGHT_ZOOM.MUL_1);
                    esc.addText(goods.getGoodsName() + getLineWithBlankChar(goods.getGoodsName().length() * 2) + "     x" + goods.getGoodsQty() + "\n");
                }
            }

            esc.addText("\n-------------------------------\n\n");

            esc.addSelectJustification(EscCommand.JUSTIFICATION.LEFT);
            esc.addSetCharcterSize(EscCommand.WIDTH_ZOOM.MUL_1, EscCommand.HEIGHT_ZOOM.MUL_1);

            esc.addText("地址：" + order.getReceiverAddr() + "\n");
            esc.addText("电话：" + order.getReceiverPhone() + "\n");
            esc.addText("姓名：" + order.getReceiverName() + "\n");

            esc.addText("\n*******************************\n");

            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
            esc.addSetCharcterSize(EscCommand.WIDTH_ZOOM.MUL_1, EscCommand.HEIGHT_ZOOM.MUL_1);
            esc.addText("订单号：" + order.getOrderId() + "\n\n");

            esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);
            esc.addSelectErrorCorrectionLevelForQRCode((byte) 0x31); //设置纠错等级
            esc.addSelectSizeOfModuleForQRCode((byte) 7);//设置qrcode模块大小
            esc.addStoreQRCodeData(order.getOrderId());//设置qrcode内容
            esc.addPrintQRCode();//打印QRCode
            esc.addSelectJustification(EscCommand.JUSTIFICATION.LEFT);
            esc.addPrintAndLineFeed();

            esc.addText("\n\n\n\n");

            Vector<Byte> datas = esc.getCommand();

            /**
             * 获取打印份数
             */
            try {
                num = Integer.valueOf((String) SharedPreferencesUtils.get(SharedPreferencesUtils.PRINT_AMOUNT, "1"));
            } catch (NumberFormatException e) {
                e.printStackTrace();
                LogUtils.e("【TEST】NumberFormatException==>" + e.getMessage());
            }

            for (int i = 1; i < num; i++) {
                datas.addAll(esc.getCommand());
            }

            // 组装对应指令
            Byte[] Bytes = datas.toArray(new Byte[datas.size()]);
            byte[] bytes = GpUtils.ByteTo_byte(Bytes);
            String str = Base64.encodeToString(bytes, Base64.DEFAULT);

            // 打印
            String rel_Str = sendCmd2Printer(context, str);

            Bytes = null;
            bytes = null;
            str = null;

            return rel_Str;

        } catch (Exception ex0) {
            LogUtils.e("【TEST】Exception=" + ex0.getMessage());
        }

        return String.valueOf(rel);
    }

    /**
     * 打印动作
     *
     * @param context
     * @param str
     * @return
     */
    private String sendCmd2Printer(Context context, String str) {
        int rel = 0;
        /**
         * =============================打印动作=========================
         * 获取打印机当前状态。每次执行打印之前需获取打印机状态，
         * 打印机正常才能够再发送命令给打印机
         */
        try {

            if (null == myprinter) {
                myprinter = TJApp.getInstance().getmGpService();
            }
            if (myprinter == null) {
                LogUtils.e("Exception: TJApp.GpService == null");
                Toast.makeText(context, "请首先配置打印机", Toast.LENGTH_SHORT).show();
                return null;
            }

            // 发送指令。。。
            rel = myprinter.sendEscCommand(PRINTER_ID, str);
            GpCom.ERROR_CODE errorCoder = GpCom.ERROR_CODE.values()[rel];

            if (errorCoder == GpCom.ERROR_CODE.SUCCESS) {   //打印成功

                SharedPreferencesUtils.put(SharedPreferencesUtils.ORDER_PRINTED_COUNT, ++order_printed_count);
                SharedPreferencesUtils.put(SharedPreferencesUtils.DAY_MONTH_YEAR, CommandTools.getDate());
            } else {
                ToastUtils.showShort(getErrorMsg(GpCom.getErrorText(errorCoder)));
                return null;
            }
        } catch (RemoteException e) {
            LogUtils.e("【TEST】RemoteException=" + e.getMessage());
            e.printStackTrace();
            return PRINT_NO_PAPER;
        }

        return String.valueOf(rel);
    }

    private String getLineWithBlankChar(int num1) {
        String str = "";
        for (int i = 0; i < (LENGTH - num1); i++) {
            str += " ";
        }
        return str;
    }

    public String getErrorMsg(String errorCode) {

        String s;
        switch (errorCode) {
            case "Failed":
                s = "打印失败（打印机没有纸或卡纸）";
                break;
            case "timeout":
                s = "打印超时";
                break;
            case "Invalid device paramters":
                s = "打印机参数错误";
                break;
            case "Device already open":
                s = "设备已经打开";
                break;
            case "Invalid port number":
                s = "打印机端口参数错误";
                break;
            case "Invalid ip address":
                s = "打印机IP地址错误";
                break;
            case "Invalid callback object":
                s = "打印票据回调失败";
                break;
            case "Bluetooth is not support by the device":
                s = "该设备不支持蓝牙";
                break;
            case "Please open bluetooth":
                s = "请打开蓝牙";
                break;
            case "Port is not open":
                s = "打印机未连接";
                break;
            case "Invalid bluetooth address":
                s = "蓝牙端口异常";
                break;
            case "Port is disconnect":
                s = "打印机已断开";
                break;
            default:
                s = "未知错误";
        }
        return s;
    }

    public static void printTest() {

        if (null == myprinter) {
            myprinter = TJApp.getInstance().getmGpService();
        }

        if(myprinter == null){
            return;
        }

        EscCommand esc = new EscCommand();
        esc.addInitializePrinter();
        esc.addPrintAndFeedLines((byte) 3);
        esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);// 设置打印居中
        esc.addSelectPrintModes(EscCommand.FONT.FONTA, EscCommand.ENABLE.OFF, EscCommand.ENABLE.ON, EscCommand.ENABLE.ON, EscCommand.ENABLE.OFF);// 设置为倍高倍宽
        esc.addText("打印机测试\n"); // 打印文字
        esc.addPrintAndLineFeed();

		/* 打印文字 */
        esc.addSelectPrintModes(EscCommand.FONT.FONTA, EscCommand.ENABLE.OFF, EscCommand.ENABLE.OFF, EscCommand.ENABLE.OFF, EscCommand.ENABLE.OFF);// 取消倍高倍宽
        esc.addSelectJustification(EscCommand.JUSTIFICATION.LEFT);// 设置打印左对齐
        esc.addText("Welcome to use printer!\n\n"); // 打印文字

		/* 打印繁体中文 需要打印机支持繁体字库 */
//        String message = "打印机测试\n";
        // esc.addText(message,"BIG5");
//        esc.addText(message, "GB2312");
//        esc.addPrintAndLineFeed();

		/* 绝对位置 具体详细信息请查看GP58编程手册 */
        esc.addText(CommandTools.getTime() + "\n\n");

		/* 打印图片 */
//        esc.addText("Print bitmap!\n"); // 打印文字
//        Bitmap b = BitmapFactory.decodeResource(TJApp.getInstance().getResources(), R.drawable.gprinter);
//        esc.addRastBitImage(b, 384, 0); // 打印图片

		/* 打印一维条码 */
        esc.addText("Print code128\n\n"); // 打印文字
        esc.addSelectPrintingPositionForHRICharacters(EscCommand.HRI_POSITION.BELOW);//
        // 设置条码可识别字符位置在条码下方
        esc.addSetBarcodeHeight((byte) 60); // 设置条码高度为60点
        esc.addSetBarcodeWidth((byte) 1); // 设置条码单元宽度为1
        esc.addCODE128(esc.genCodeB("SMARNET")); // 打印Code128码
        esc.addPrintAndLineFeed();

		/*
		 * QRCode命令打印 此命令只在支持QRCode命令打印的机型才能使用。 在不支持二维码指令打印的机型上，则需要发送二维条码图片
		 */
//        esc.addText("Print QRcode\n"); // 打印文字
//        esc.addSelectErrorCorrectionLevelForQRCode((byte) 0x31); // 设置纠错等级
//        esc.addSelectSizeOfModuleForQRCode((byte) 3);// 设置qrcode模块大小
//        esc.addStoreQRCodeData("www.smarnet.cc");// 设置qrcode内容
//        esc.addPrintQRCode();// 打印QRCode
//        esc.addPrintAndLineFeed();

		/* 打印文字 */
        esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);// 设置打印左对齐
        esc.addText("打印结束\r\n"); // 打印结束

        esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);// 设置打印左对齐
        esc.addText("-----------------------------\n"); // 打印文字

        // 开钱箱
        esc.addGeneratePlus(LabelCommand.FOOT.F5, (byte) 255, (byte) 255);
        esc.addPrintAndFeedLines((byte) 5);

        Vector<Byte> datas = esc.getCommand(); // 发送数据
        byte[] bytes = com.gprinter.command.GpUtils.ByteTo_byte(datas);
        String sss = Base64.encodeToString(bytes, Base64.DEFAULT);
        int rs;
        try {
            rs = myprinter.sendEscCommand(0, sss);
            GpCom.ERROR_CODE r = GpCom.ERROR_CODE.values()[rs];
            if (r != GpCom.ERROR_CODE.SUCCESS) {
                ToastUtils.showShort(GpCom.getErrorText(r));
            }else{
                ToastUtils.showShort("打印成功");
            }
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
